package com.iflytek.jzcpx.procuracy.common.result;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.iflytek.jzcpx.procuracy.common.enums.CommonResultEnum;
import com.iflytek.jzcpx.procuracy.common.enums.ResultType;
import lombok.Data;

/**
 * 统一结果对象
 * @author <a href=mailto:ktyi@iflytek.com>伊开堂</a>
 * @date 2019-08-06 14:04
 */
@Data
@JsonIgnoreProperties({"fileId"})
public class Result<T> {
    /** 请求是否成功 */
    private boolean success;

    /** 失败请求错误详情 */
    private ErrorDetail error;

    /** 结果数据 */
    private T data;
    
    /**
     * fileId 指标收集用
     */
    private Long fileId;

    private Result() {
    }

    public Result(ResultType resultType) {
        if (resultType.isSuccess()) {
            this.success = true;
        }
        else {
            this.error = new ErrorDetail(resultType);
        }
    }

    public Result(ResultType resultType, T data) {
        this(resultType);
        this.data = data;
    }

    public Result(ResultType resultType, String customMsg) {
        this(resultType);
        this.error.setMsg(customMsg);
    }

    public static Result from(Result otherResult) {
        Result result = new Result<>();
        result.setError(otherResult.getError());
        return result;
    }

    public boolean isSuccess() {
        return error != null && error.getCode() == ResultType.SUCCESS || success;
    }

    public void setSuccess(boolean success) {
        this.success = success;
    }

    /** 构造的成功响应 */
    public static <T> Result<T> success(T data) {
        return new Result<>(CommonResultEnum.SUCCESS, data);
    }
    
    /** 构造的成功响应 */
    public static <T> Result<T> success(T data,Class<T> t) {
        return new Result<T>(CommonResultEnum.SUCCESS, data);
    }

    /** 构造无结果的成功响应 */
    public static Result success() {
        return new Result<>(CommonResultEnum.SUCCESS);
    }

    /** 构造自定义错误信息的默认失败响应 */
    public static Result failed(ResultType resultType) {
        if (resultType == null || resultType.getCode().equals(ResultType.SUCCESS)) {
            throw new IllegalArgumentException("结果状态枚举必须是失败类枚举");
        }
        return new Result<>(resultType);
    }
    
    /** 构造自定义错误信息的默认失败响应 */
    public static <T> Result<T> failed(ResultType resultType,Class<T> t) {
        if (resultType == null || resultType.getCode().equals(ResultType.SUCCESS)) {
            throw new IllegalArgumentException("结果状态枚举必须是失败类枚举");
        }
        return new Result<>(resultType);
    }
    
    /** 构造自定义错误信息的默认失败响应 */
    public static <T> Result<T> failed(ResultType resultType, String customMsg,Class<T> t) {
        if (resultType == null || resultType.getCode().equals(ResultType.SUCCESS)) {
            throw new IllegalArgumentException("结果状态枚举必须是失败类枚举");
        }
        return new Result<>(resultType);
    }

    /** 构造自定义错误信息的默认失败响应 */
    public static Result failed(String customMsg) {
        return new Result<>(CommonResultEnum.FAILED, customMsg);
    }

    /** 构造自定义错误码和错误信息的失败响应 */
    public static Result failed(ResultType resultEnum, String customMsg) {
        return new Result<>(resultEnum, customMsg);
    }

    public Result<T> update(ResultType resultType) {
        if (resultType.isSuccess()) {
            this.success = true;
        }
        else {
            this.error = new ErrorDetail(resultType);
        }
        return this;
    }

    public Result<T> update(ResultType resultType, String customMsg) {
        if (resultType.isSuccess()) {
            this.success = true;
        }
        else {
            this.error = new ErrorDetail(resultType);
            this.error.setMsg(customMsg);
        }
        return this;
    }
}
